#ifndef TABLEMANAGER_H_
#define TABLEMANAGER_H_

#include <vector>
#include <string>
#include "Interfaces.h"
#include "SymbolsTable.h"
#include "FunctionEntry.h"

#define DEBUG_SYM_TAB 0

typedef std::vector<SymbolTable*> SymTabVec; // Types.h ??

class TableManager : public SymbolTableInterface
{
public:
	TableManager();
	virtual ~TableManager();
	
	void createNewTable();
	void discardCurrentTable();
	
	bool search(std::string identifier, TableEntry* &tabEntry);
	void insert(std::string identifier, TableEntry* tabEntry);
	
	bool search(Token &tkIdentifier);
	bool search(Token &tkIdentifier, TableEntry* &tabEntry);
	void insert(Token &tkIdentifier, TableEntry* tabEntry);
	
	void registerObserver(FunctionObserver* o);

	int getNextAddress();
	const FunctionEntry* const getCurrentFunction();
	std::ostream& inserter(std::ostream &os) const;

private:
	SymbolTable* currentTable;
	
	SymTabVec inScope;
	SymTabVec outOfScope;
	
	std::vector<FunctionObserver*> functionObservers;
	FunctionEntry* currentFunction;
	
	int currentAddress;
	static const int FUNCTION_BASE_ADDRESS = 16; // TODO unify this with the MoonGen's CONST_BOOKKEEPING_SZ
	static const int ADDRESS_INCREMENT = 4;
	
	void notifyFunctionObservers(std::string functionLabel, int functionSize);
};

#endif /*TABLEMANAGER_H_*/
